/*
 * gpio-ss805x.c
 *
 * The gpio driver for SS805X.
 *
 * Copyright (C) 2024 Sinh Micro, Inc.
 * Subject to the GNU Public License, version 2.
 *
 * Author: lixiang<lixiang@sinhmicro.com>
 * 
 * Encoding format: GB2312
 * Version: v1.2.2
 * Date: 2024-11-05
 */

#include "hal-config.h"
#include "hal-regs.h"

#include "types.h"
#include "system.h"
#include "gpio.h"

#if (defined(CONFIG_SYS_CHIP_SERIES_SS805X))

/*
 * this function is used to initialize the GPIO driver.
 *
 * @param[in]  None
 */
void gpio_init(void)
{

}

/*
 * this function is used to set the I/O port's MFP.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 * @param[in]  mfp_val  MFP value, 0~3, or 0~7
 */
void gpio_mfp_set(uint8_t port, uint8_t num, uint8_t mfp_val)
{
    port = port;
    num = num;
    mfp_val = mfp_val;
}

/*
 * this function is used to set the GPIO to input mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_input_mode_enable(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_IM_EN(bitmask);
        break;

    case 1:
        GPIO_P1_0_4_IM_EN(bitmask);
        break;

    default:
        break;
    }  
}

/*
 * this function is used to set the GPIO to output mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_output_mode_enable(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_OM_EN(bitmask);
        break;

    case 1:
        GPIO_P1_0_4_OM_EN(bitmask);
        break;

    default:
        break;
    }  
}

/*
 * this function is used to set the GPIO to high-z mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_highz_mode_enable(uint8_t port, uint8_t num)
{
    port = port;
    num = port;
}

/*
 * this function is used to set the GPIO to output high.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_output_high(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_OUTPUT_HIGH(bitmask);
        break;

    case 1:
        GPIO_P1_0_4_OUTPUT_HIGH(bitmask);
        break;

    default:
        break;
    }
}

/*
 * this function is used to set the GPIO to output low.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_output_low(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_OUTPUT_LOW(bitmask);
        break;

    case 1:
        GPIO_P1_0_4_OUTPUT_LOW(bitmask);
        break;

    default:
        break;
    }
}


/*
 * this function is used to get the GPIO's input value.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 * @return 1 or 0 for the input value
 */
bit_t gpio_input_value_get(uint8_t port, uint8_t num)
{
    uint8_t val;

    switch (port) {
    case 0:
        val = GPIO_P0_INPUT_VAL_GET();
        break;

    case 1:
        val = GPIO_P1_0_4_INPUT_VAL_GET();
        break;

    default:
        val = 0;
        break;
    }
    
    return !!(val & (1 << num));
}

/*
 * this function is used to set the GPIO to pull-up mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_pull_up_mode_enable(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_PU_EN(bitmask);
        break;

    case 1:
        if (num < 4)
            GPIO_P1_0_3_PU_EN(bitmask);
        else if (num < 5)
            GPIO_P14_PU_EN(bitmask);
        break;

    default:
        break;
    }
}

/*
 * this function is used to set the GPIO to pull-down mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_pull_down_mode_enable(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_PD_EN(bitmask);
        break;

    case 1:
        if (num < 4)
            GPIO_P1_0_3_PD_EN(bitmask);
        else if (num < 5)
            GPIO_P14_PD_EN(bitmask);
        break;

    default:
        break;
    }
}

/*
 * this function is used to set the GPIO to no-pull mode.
 *
 * @param[in]  port     I/O's port, 0, 1.
 * @param[in]  num      I/O's num, 0~7
 */
void gpio_no_pull_mode_enable(uint8_t port, uint8_t num)
{
    uint8_t bitmask = (1 << num);

    switch (port) {
    case 0:
        GPIO_P0_NP_EN(bitmask);
        break;

    case 1:
        if (num < 4)
            GPIO_P1_0_3_NP_EN(bitmask);
        else if (num < 5)
            GPIO_P14_NP_EN(bitmask);
        break;

    default:
        break;
    }
}
#endif
